package cn.com.blueInfo.bpm.system.service.impl;

import cn.com.blueInfo.bpm.system.convert.MenuConvert;
import cn.com.blueInfo.bpm.system.entity.Menu;
import cn.com.blueInfo.bpm.system.enums.MenuType;
import cn.com.blueInfo.bpm.system.repository.MenuRepository;
import cn.com.blueInfo.bpm.system.request.MenuDTO;
import cn.com.blueInfo.bpm.system.response.MenuVO;
import cn.com.blueInfo.bpm.system.service.MenuService;
import cn.com.blueInfo.core.util.SnowflakeIdGenerator;
import cn.com.blueInfo.utils.result.ResultInfo;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 菜单表 业务服务实现类
 * @author suxch
 * @since 2025-09-01 19:17:41
 */
@Log4j2
@Service
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuRepository menuRepository;

    @Autowired
    private SnowflakeIdGenerator snowflakeIdGenerator;

    @Autowired
    private MenuConvert menuConvert;

    /**
     * 新增菜单
     * @param menuDTO 菜单参数
     */
    @Override
    public ResultInfo<Integer> addMenu(MenuDTO menuDTO) {
        Menu menu = menuConvert.dtoToEntity(menuDTO);
        menu.setId(snowflakeIdGenerator.nextId());
        Integer addSize = menuRepository.createMenu(menu);
        return ResultInfo.<Integer>builder().data(addSize).message("菜单成功新增 {} 条").build();
    }

    /**
     * 批量新增菜单
     * @param menuDTOList 菜单参数列表
     */
    @Override
    public ResultInfo<Integer> batchAddMenu(List<MenuDTO> menuDTOList) {
        List<Menu> menuList = menuConvert.dtoToEntity(menuDTOList);
        for (Menu menu : menuList) menu.setId(snowflakeIdGenerator.nextId());
        Integer addSize = menuRepository.batchCreateMenu(menuList);
        return ResultInfo.<Integer>builder().data(addSize).message("菜单成功新增 {} 条").build();
    }

    /**
     * 删除菜单
     * @param menuId 菜单ID
     */
    @Override
    public ResultInfo<Integer> removeMenu(Long menuId) {
        Integer removeSize = menuRepository.deleteMenu(menuId);
        return ResultInfo.<Integer>builder().data(removeSize).message("菜单成功删除 {} 条").build();
    }

    /**
     * 批量删除菜单
     * @param menuIdList 菜单ID列表
     */
    @Override
    public ResultInfo<Integer> batchRemoveMenu(List<Long> menuIdList) {
        Integer removeSize = menuRepository.batchDeleteMenu(menuIdList);
        return ResultInfo.<Integer>builder().data(removeSize).message("菜单成功删除 {} 条").build();
    }

    /**
     * 更新部分菜单
     * @param menuUpdatePartialDTO 菜单参数
     */
    @Override
    public ResultInfo<Integer> modifyMenuPartial(MenuDTO.UpdatePartialDTO menuUpdatePartialDTO) {
        Menu menu = menuConvert.dtoToEntity(menuUpdatePartialDTO);
        Integer modifySize = menuRepository.updateMenuPartial(menu);
        return ResultInfo.<Integer>builder().data(modifySize).message("菜单成功更新 {} 条").build();
    }

    /**
     * 更新全部菜单
     * @param menuDTO 菜单参数
     */
    @Override
    public ResultInfo<Integer> modifyMenu(MenuDTO menuDTO) {
        Menu menu = menuConvert.dtoToEntity(menuDTO);
        Integer modifySize = menuRepository.updateMenu(menu);
        return ResultInfo.<Integer>builder().data(modifySize).message("菜单成功更新 {} 条").build();
    }

    /**
     * 查询一条菜单
     * @param menuId 菜单ID
     */
    @Override
    public ResultInfo<MenuVO> queryMenuById(Long menuId) {
        Menu menu = menuRepository.getMenuById(menuId);
        MenuVO menuVO = menuConvert.entityToVO(menu);
        return ResultInfo.<MenuVO>builder().data(menuVO).message("菜单查询成功").build();
    }

    /**
     * 分页查询菜单
     * @param menuQueryDTO 菜单参数
     */
    @Override
    public ResultInfo<Page<MenuVO>> queryMenuPage(MenuDTO.QueryDTO menuQueryDTO) {
        Page<Menu> menuPage = menuRepository.getMenuPage(menuQueryDTO);
        Page<MenuVO> resultData = menuConvert.convertPage(menuPage);
        return ResultInfo.<Page<MenuVO>>builder()
                .data(resultData)
                .message("菜单分页查询成功，共 {} 条", resultData.getRecords().size())
                .build();
    }

    /**
     * 根据条件查询 菜单 数量
     * @param menuQueryDTO 菜单参数
     */
    @Override
    public ResultInfo<Long> queryMenuCount(MenuDTO.QueryDTO menuQueryDTO) {
        Long resultCount = menuRepository.getMenuCount(menuQueryDTO);
        return ResultInfo.<Long>builder()
                .data(resultCount)
                .message("菜单数量查询成功，共 {} 条", resultCount)
                .build();
    }

    /**
     * 获取平台管理菜单
     */
    @Override
    public ResultInfo<List<MenuVO>> querySystemMenu() {
        MenuDTO.QueryDTO menuQueryDTO = new MenuDTO.QueryDTO();
        menuQueryDTO.setMenuType(MenuType.SYSTEM_MENU);
        ResultInfo<List<MenuVO>> resultInfoList = queryMenuList(menuQueryDTO);
        List<MenuVO> menuVOList = resultInfoList.getData();

        // 1. 缓存所有菜单（id -> 菜单对象）
        Map<String, MenuVO> menuMap = menuVOList.stream()
                .peek(entity -> {
                    String routePath = entity.getRoutePath();
                    String[] routePathArr = routePath.split("/");
                    entity.setName(routePathArr[routePathArr.length - 1]);
                })
                .collect(Collectors.toMap(MenuVO::getId, vo -> vo));

        // 2. 组装树形结构
        List<MenuVO> rootMenus = new ArrayList<>();
        for (MenuVO vo : menuMap.values()) {
            if (Long.parseLong(vo.getParentId()) == -1) {
                // 一级菜单，直接加入根列表
                rootMenus.add(vo);
            } else {
                // 二级菜单，找到父菜单并加入其子列表
                MenuVO parent = menuMap.get(vo.getParentId());
                if (parent != null) {
                    if (parent.getChildren() == null) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(vo);
                }
            }
        }

        return ResultInfo.<List<MenuVO>>builder()
                .data(rootMenus)
                .message("系统菜单查询成功，共 {} 条", resultInfoList.getData().size())
                .build();
    }

    /**
     * 根据条件查询 菜单
     * @param menuQueryDTO 菜单参数
     */
    @Override
    public ResultInfo<List<MenuVO>> queryMenuList(MenuDTO.QueryDTO menuQueryDTO) {
        List<Menu> menuList = menuRepository.getMenuList(menuQueryDTO);
        List<MenuVO> resultData = menuConvert.entityListToVoList(menuList);
        return ResultInfo.<List<MenuVO>>builder()
                .data(resultData)
                .message("菜单分页查询成功，共 {} 条", resultData.size())
                .build();
    }

}
